package org.wu.framework.inner.lazy.orm.spring.prop;

import lombok.Data;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.springframework.context.annotation.Role;
import org.wu.framework.core.NormalUsedString;
import org.wu.framework.lazy.orm.core.config.ddl.AbstractLazyDdlConfigureAttribute;
import org.wu.framework.lazy.orm.core.config.enums.DDLAuto;
import org.wu.framework.lazy.orm.core.config.prop.SchemaScript;
import org.wu.framework.lazy.orm.core.persistence.conf.LazyDatabaseJsonMessage;
import org.wu.framework.lazy.orm.core.persistence.conf.mysql.FieldLazyTableFieldEndpoint;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * DDL 忽略属性
 */
@Data
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@ConfigurationProperties(prefix = LazyDdlSpringProperties.LAZY_DDL_PROPERTIES_PREFIX)
public class LazyDdlSpringProperties extends AbstractLazyDdlConfigureAttribute implements InitializingBean {

    public static final String LAZY_DDL_PROPERTIES_PREFIX = "spring.lazy.ddl-configure";
    /**
     * DDL  操作
     */
    private DDLAuto ddlAuto = DDLAuto.UPDATE;
    /**
     * DDL 完善表承诺书
     * 此操作会删除字段完全按照模型完善表⚠️
     */
    private String ddlPerfectCommitment;
    /**
     * DDL 忽略字段
     */
    private List<String> ddlIgnoredFields = Arrays.asList("id");
    /**
     * DDL 忽略表前缀
     */
    private List<String> ddlIgnoredTablePrefix = Arrays.asList();

    /**
     * DDL 忽略表后缀 天然适应Uo
     */
    private List<String> ddlIgnoredTableSuffix = Arrays.asList("Uo");
    /**
     * 是否开启额外字段
     */
    private Boolean enableExtraFields = false;
    /**
     * 额外的字段 当 enableExtraFields=true 时有效
     * <p>
     * "`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',\n" +
     * "`is_deleted` tinyint(1) DEFAULT '0' COMMENT '是否删除',\n" +
     * "`create_time` datetime DEFAULT CURRENT_TIMESTAMP  COMMENT '创建时间',\n" +
     * "`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n" +
     * "PRIMARY KEY (`id`) USING BTREE\n";
     *
     * <p>
     * spring:
     * lazy:
     * ddl-configure:
     * ddl-ignored-table-suffix:
     * - DO
     * ddl-auto: perfect
     * extra-fields:
     * - name: isDelete
     * columnName: is_delete
     * columnType: tinyint(1)
     * comment: 是否删除
     * defaultValue: '0'
     * exist: true
     * </p>
     */
    private List<FieldLazyTableFieldEndpoint> extraFields = new ArrayList<FieldLazyTableFieldEndpoint>() {
        {
            FieldLazyTableFieldEndpoint id = new FieldLazyTableFieldEndpoint();
            id.setName("id");
            id.setColumnType("bigint(20)");
            id.setColumnName("id");
            id.setClazz(Long.class);
            id.setComment("主键");
            id.setNotNull(true);
            id.setExtra(NormalUsedString.AUTO_INCREMENT);
            id.setKey(true);
            add(id);

            FieldLazyTableFieldEndpoint isDeleted = new FieldLazyTableFieldEndpoint();
            isDeleted.setName("isDeleted");
            isDeleted.setColumnType("tinyint(1)");
            isDeleted.setDefaultValue("0");
            isDeleted.setColumnName("is_deleted");
            isDeleted.setComment("是否删除");
            add(isDeleted);

            FieldLazyTableFieldEndpoint createTime = new FieldLazyTableFieldEndpoint();
            createTime.setName("createTime");
            createTime.setColumnType("datetime");
            createTime.setDefaultValue("CURRENT_TIMESTAMP");
            createTime.setColumnName("create_time");
            createTime.setComment("创建时间");
            add(createTime);

            FieldLazyTableFieldEndpoint updateTime = new FieldLazyTableFieldEndpoint();
            updateTime.setName("updateTime");
            updateTime.setColumnType("datetime");
            updateTime.setColumnName("update_time");
            updateTime.setDefaultValue("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP");
            updateTime.setComment("更新时间");
            add(updateTime);
        }
    };

    /**
     * 初始化脚本
     */
    @NestedConfigurationProperty
    private SchemaScript schemaScript = new SchemaScript();

    /**
     * 导出表结构
     */
    private boolean outPutTableStructure = false;

    /**
     * Invoked by the containing {@code BeanFactory} after it has set all bean properties
     * and satisfied {@link BeanFactoryAware}, {@code ApplicationContextAware} etc.
     * <p>This method allows the bean instance to perform validation of its overall
     * configuration and final initialization when all bean properties have been set.
     *
     * @throws Exception in the event of misconfiguration (such as failure to set an
     *                   essential property) or if initialization fails for any other reason
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        LazyDatabaseJsonMessage.ddlIgnoredFields = getDdlIgnoredFields();
        LazyDatabaseJsonMessage.ddlIgnoredTablePrefix = getDdlIgnoredTablePrefix();
        LazyDatabaseJsonMessage.ddlIgnoredTableSuffix = getDdlIgnoredTableSuffix();
        LazyDatabaseJsonMessage.extraFields = getEnableExtraFields() ? getExtraFields() : new ArrayList<>();
    }
}